/**
 * @Project: YunPayDemo
 * @Title: BaseAction.java
 * @Package com.yunpay.demo.pay.web
 * @Description: TODO(用一句话描述该文件做什么)
 * @author guxq12519 guxq12519@hundsun.com
 * @date 2015年6月6日 上午11:00:26
 * @Copyright: 2015 www.hundsun.com All Rights Reserved.
 * @version V1.0.0.0
 */

package com.cloudbroker.bcs.platform.ltb.common.payUtil.web;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.cloudbroker.bcs.platform.ltb.common.payUtil.EncryptUtil;
import com.cloudbroker.bcs.platform.ltb.common.payUtil.HttpUtils;
import com.cloudbroker.bcs.platform.ltb.common.payUtil.RSAUtils;
import com.cloudbroker.bcs.platform.ltb.common.payUtil.SHA256Util;
import com.cloudbroker.bcs.platform.ltb.common.payUtil.bean.OrderRequest;
import org.springframework.beans.factory.annotation.Value;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.Map;


/**
 * @ClassName BaseAction
 * @Description TODO
 * @author guxq12519 guxq12519@hundsun.com
 * @date 2015年6月6日
 */
public class BaseAction {
	@Value("/resource/test.pfx")
	private String certFile;
	@Value("test")
	private String certPasswd;
	@Value("http://test.epay.hsjry.com:2800/eis/yunpay")
	private String test_gateway_url;
	/*
	 * 摘要+加签+发送
	 */
	protected String proceed(OrderRequest request, String method) throws Exception {
	    String extend_info=request.getExtend_info();
		Map<String, Object> map = checkAndInsert (request);

		String post_url = test_gateway_url + "/" + method;
		System.out.println ("请求地址:" + post_url);
		String source = EncryptUtil.sortSource (map); // 原文排序
		System.out.println ("加签原文:" + source);
		source = SHA256Util.getSHA256 (source); // 对原文做摘要算法
		System.out.println ("加签摘要:" + source);
		//获取私钥证书
		String key_file = BaseAction.class.getClassLoader ().getResource (certFile).getPath ();
		//对摘要加签
		String sign = RSAUtils.sign (source.getBytes (), key_file, certPasswd, null);

		System.out.println ("签名应答:" + sign);
		map.put ("cert_sign", sign);
		map.remove("extend_info_list");
		map.put("extend_info", extend_info);
		String resp;
		try {
			resp = HttpUtils.doPost (post_url, map);
			boolean result = false;
			if ("epay_apply_check_file".equals (method) || "epay_query_orders".equals (method)) {
				if (resp.contains ("\n")) {
					dealWithFile (resp);
				} else {
					return resp;
				}
			} else {
				String certFile = BaseAction.class.getClassLoader ().getResource ("/resource/yunpay.cer").getPath ();
				String cert_sign = null; //获取返回的报文中的签名串

                JSONObject jsonObj = (JSONObject) JSON.parse(resp);
                /*
                 * 成功响应报文格式为{data:[{"pay_status":"3","cert_sign":"sign"}]}
                 * 失败响应报文格式为{"error_no":"999999","error_info":"error","error_code":"999999","error_extinfo":"error","cert_sign":"sign"}
                 */
                if (jsonObj.getJSONArray("data") != null) {
                    jsonObj = jsonObj.getJSONArray("data").getJSONObject(0);
                }
                cert_sign = jsonObj.getString("cert_sign");
                jsonObj.remove("cert_sign");

                /* 拼装签名要素，排序 */
				String content = EncryptUtil.sortSource (jsonObj);
				System.out.println("验签原文：" + content);

				/* 签名要素摘要，摘要算法SHA-256 */
				content = SHA256Util.getSHA256 (content);
				System.out.println("验签摘要：" + content);

				/* 验签 ，签名算法SHA1withRSA*/
				result = RSAUtils.verifyByCert (content.getBytes ("UTF-8"), certFile, cert_sign);

				System.out.println("验签结果：" + result);
			}

			System.out.println("doPost应答：" + resp);
		}
		catch (Exception e) {
			System.out.println("doPost失败"+e);
			return "doPost失败" + e;
		}
		return resp;
	}

	/**
	 * method comments here
	 * @param resp
	 * @throws Exception
	 * @throws UnsupportedEncodingException
	 * @throws IOException
	 */
	protected void dealWithFile(String resp) throws Exception, UnsupportedEncodingException, IOException {
		boolean result;
		String content = resp.substring (0, resp.lastIndexOf ("\n"));
		String signStr = resp.substring (resp.lastIndexOf ("\n") + 1, resp.length ());
		result = RSAUtils.verifyByCert (SHA256Util.getSHA256 (content).getBytes ("UTF-8"), BaseAction.class.getClassLoader ()
				.getResource ("/resource/yunpay.cer").getPath (), signStr);
		System.out.println("验签结果:" + result);
	}

	/**
	 * @return
	 * @Method checkAndInsert
	 * @Description 检查提交的表单，非空则插入到map中
	 * @param @field
	 * @return void
	 * @throws
	 */
	protected Map<String, Object> checkAndInsert(OrderRequest request) {

		if (null != request.getDetail () && !"".equals (request.getDetail ())) {
			@SuppressWarnings ("unchecked")
			List<OrderRequest> list = JSONObject.parseObject (request.getDetail (), List.class);
			request.setDetails (list);
			request.setDetail (null);
		}
		if (null != request.getExtend_info() && !"".equals (request.getExtend_info ())) {
		    @SuppressWarnings ("unchecked")
		    List<OrderRequest> list = JSONObject.parseObject (request.getExtend_info(), List.class);
		    request.setExtend_info_list(list);
		    request.setExtend_info (null);
		}
		@SuppressWarnings ("unchecked")
		Map<String, Object> map = (Map<String, Object>) JSONObject.parse (JSONObject.toJSONString (request));

		return map;
	}

	protected Map<String, Object> checkAndInsert(String response) {
		@SuppressWarnings ("unchecked")
		Map<String, Object> map = (Map<String, Object>) JSONObject.parse (response);
		map.remove ("cert_sign");
		return map;
	}
}
